package com.yueyang.sojourn.server.service.sojourn.share;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yueyang.sojourn.server.config.WxPayProperties;
import com.yueyang.sojourn.server.model.enums.PayConstants;
import com.yueyang.sojourn.server.model.enums.ShareConstans;
import com.yueyang.sojourn.server.model.enums.StatusEnum;
import com.yueyang.sojourn.server.model.po.*;
import com.yueyang.sojourn.server.service.sojourn.merchant.SojournMerchantService;
import com.yueyang.sojourn.server.service.sojourn.order.SojournOrderService;
import com.yueyang.sojourn.server.service.sojourn.projectshare.SojournProjectShareService;
import com.yueyang.sojourn.server.service.sojourn.sequence.SojournSequnceManager;
import com.yueyang.sojourn.server.service.sojourn.transaction.SojournTransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 分账单服务
 * @author andy.yang
 * @version v1
 * @summary
 * @Copyright (c) 2019, yueyang Group All Rights Reserved.
 * @since 2020/3/30
 */
@Service
public class SojournShareService {
    @Resource
    SojournShareMapper sojournShareMapper;
    @Autowired
    SojournShareDetailService detailService;
    @Autowired
    SojournOrderService orderService;
    @Autowired
    SojournProjectShareService projectShareService;
    @Autowired
    SojournMerchantService merchantService;
    @Autowired
    SojournTransactionService transactionService;
    @Autowired
    SojournSequnceManager sequnceManager;
    @Autowired
    WxPayProperties wxPayProperties;

    /**
     * 创建分账单
     * @param
     * @return
     */
    @Transactional
    public int add(Long orderId,Long userId){
        SojournOrder order = orderService.findById(orderId);
        SojournTransaction transaction = transactionService.findPayByOrderSn(order.getSn());
        SojournMerchant merchant = merchantService.findByProjectId(order.getMerchProjectId());
        //创建分账单
        SojournShare share = new SojournShare();
        share.setOrderId(orderId);
        share.setSn(sequnceManager.nextValueOfShare());
        share.setTransactionId(transaction.getId());
        share.setThirdTransactionId(transaction.getThirdTransId());
        share.setThirdMerchantNo(merchant.getWxMerchantNo());
        share.setTotalFee(order.getTotalPrice().multiply(new BigDecimal(100)).intValue());
        share.setStatus(ShareConstans.ShareStatusEnum.TO_SHARE.getCode());
        share.setCreator(userId);
        sojournShareMapper.insert(share);

        //创建子账单
        List<SojournProjectShare> projectShareList = projectShareService.findListByProjectId(order.getMerchProjectId());
        List<SojournShareDetail> details = new ArrayList<>();


        String platformMchId = wxPayProperties.getMchId();//平台的商户号（服务商模式时，mchId即是
        //每个分账接收方应该分的钱；
        Integer othersTotalFee = 0;
        for(SojournProjectShare projectShare : projectShareList){
            SojournShareDetail detail = new SojournShareDetail();
            detail.setShareId(share.getId());
            detail.setReceiverId(projectShare.getReceiverId());
            detail.setReceiverType(projectShare.getReceiverType());
            detail.setPrime(projectShare.getPrime());
            if(PayConstants.ThirdPayAccountTypeEnum.WX_MERCHANT.getCode().equals(projectShare.getReceiverType())){
                SojournMerchant merchantReceiver = merchantService.findById(detail.getReceiverId());
                //平台此处不参与分账配置；下一步统一处理
                if(merchantReceiver.getWxMerchantNo().equals(platformMchId)){
                    continue;
                }
                detail.setReceiverThirdNo(merchantReceiver.getWxMerchantNo());//接收方在第三方支付中的号
            }else{
                //todo
            }
//            projectShare.getThirdSynStatus() todo 必须保证接收方一定已经成功配置
            ;
            Integer shareFee = order.getTotalPrice().multiply(projectShare.getShareRatio()).setScale(0, BigDecimal.ROUND_DOWN).intValue();
            othersTotalFee += shareFee;
            detail.setFee(shareFee);
            detail.setStatus(StatusEnum.VALID.getCode());
            detail.setCreator(userId);
            details.add(detail);
        }

        //平台应该分的钱
        Integer platformFee = order.getTotalPrice().multiply(new BigDecimal(100)).intValue() - othersTotalFee;
        if(platformFee < 0){
            throw new RuntimeException("订单id[" + orderId + "]平台分账为负数：" + platformFee);
        }
        SojournShareDetail detail = new SojournShareDetail();
        detail.setShareId(share.getId());
        detail.setReceiverId(-1L);//写死在项目中
        detail.setReceiverType(PayConstants.ThirdPayAccountTypeEnum.WX_MERCHANT.getCode());
        detail.setReceiverThirdNo(platformMchId);//接收方在第三方支付中的号; 即平台的商户号
        detail.setFee(platformFee);
        detail.setStatus(StatusEnum.VALID.getCode());
        detail.setCreator(userId);
        detail.setPrime(false);
        details.add(detail);

        return detailService.addBatch(details);
    }

    /**
     * 修改分账单状态
     * @param share
     * @return
     */
    public int updateThirdShareIdAndStatus(SojournShare share){
        return sojournShareMapper.updateThirdShareIdAndStatus(share);
    }

    /**
     * @param userId      所属用户id
     * @param pageNo      页码
     * @param pageSize    页大小
     * @return
     * @author Andy.yang
     * @summary 订单分页查询
     * @version v1
     * @since 2020-02-19
     */
    public PageInfo<SojournShare> findPage(Long userId, Integer status,int pageNo, int pageSize) {
        PageInfo<SojournShare> pageInfo = PageHelper.startPage(pageNo, pageSize)
                .doSelectPageInfo(() -> sojournShareMapper.findBy(userId,status));
        return pageInfo;
    }

    /**
     * @param shareId      分账单id
     * @return
     * @author Andy.yang
     * @summary 订单分页查询
     * @version v1
     * @since 2020-02-19
     */
    public SojournShare findById(Long shareId) {
        return sojournShareMapper.selectByPrimaryKey(shareId);
    }
}
